/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.celephais.objectGenerator.fileGenerators;

import com.celephais.objectGenerator.FieldDetailPanel;
import com.celephais.objectGenerator.FieldDetailPanel.FieldType;
import com.celephais.objectGenerator.ObjectGenerator;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Eugene Shen
 */
public class ServerModelGenerator extends FileGenerator {

	protected static final String SERVER_MODEL_TEMPL_DIR = "templates" + File.separator + "serverModel" + File.separator;

	private String declSimple = null;
	private String declRef = null;
	private String accessSimple = null;
	private String accessText = null;
	private String accessRef = null;

	public ServerModelGenerator(ObjectGenerator parent) {
		super(parent);
	}

	@Override
	public String getTemplateDir() {
		return SERVER_MODEL_TEMPL_DIR;
	}

	@Override
	public String getFileName(String baseClassName) {
		return baseClassName;
	}

	@Override
	public String generateAdditional(String fileContents) {
		// Variables
		String varDecl = generateVarDecl();
		if (varDecl != null) {
			fileContents = fileContents.replaceAll("%varDecl%", varDecl);
		}

		// Accessors for variables.
		String accessors = generateAccessors();
		if (accessors != null) {
			fileContents = fileContents.replaceAll("%accessors%", accessors);
		}

		return fileContents;
	}

	@Override
	public String getOutputDir(String srcDir) {
		return srcDir + File.separator + "server" + File.separator + "model";
	}

	public String getJavaType(FieldType fieldType) {
		switch (fieldType) {
			case STRING:
				return "String";
			case TEXT:
				return "Text";
			case INT:
				return "int";
			case DOUBLE:
				return "double";
			case BOOL:
				return "boolean";
			case REF:
				return "";
			case UNKNOWN:
			default:
				Logger.getLogger(ObjectGenerator.class.getName()).log(Level.SEVERE, null, (Throwable)null);
				popErrorDialog("A programmer error has resulted in a variable type being unknown.  Please contact the developer and chew him out.");
				return null;
		}
	}

	public String getDeclTemplate(FieldType fieldType) {
		if (fieldType == FieldType.UNKNOWN) {
			// TODO: Throw error?
			return null;
		}
		else if (fieldType == FieldType.REF) {
			if (declRef == null) {
				declRef = readFile(getTemplateDir(), "declRef.txt");
			}
			return declRef;
		}
		else {
			if (declSimple == null) {
				declSimple = readFile(getTemplateDir(), "declSimple.txt");
			}
			return declSimple;
		}
	}

	public String getAccessorTemplate(FieldType fieldType) {
		if (fieldType == FieldType.UNKNOWN) {
			// TODO: Throw error?
			return null;
		}
		else if (fieldType == FieldType.REF) {
			if (accessRef == null) {
				accessRef = readFile(getTemplateDir(), "accessRef.txt");
			}
			return accessRef;
		}
		else if (fieldType == FieldType.TEXT) {
			if (accessText == null) {
				accessText = readFile(getTemplateDir(), "accessText.txt");
			}
			return accessText;
		}
		else {
			if (accessSimple == null) {
				accessSimple = readFile(getTemplateDir(), "accessSimple.txt");
			}
			return accessSimple;
		}
	}

	protected String generateVarDecl() {
		StringBuilder rtn = new StringBuilder();

		for (FieldDetailPanel fdp : parent.getDetailsPanel().getFields()) {
			FieldType type = fdp.getType();
			String name = fdp.getFieldName();
			String template = getDeclTemplate(type);

			if (template != null) {
				template = template.replaceAll("%type%", getJavaType(type)).replaceAll("%varName%", name);
				if (type == FieldType.REF) {
					// TODO: Replace all occurrences of %refType% with the name of the referenced type.
				}
				rtn.append(template); //.append(CRLF);
			}
			else {
				// TODO: Throw error?
			}
		}

		return rtn.toString();
	}

	protected String generateAccessors() {
		StringBuilder rtn = new StringBuilder();

		for (FieldDetailPanel fdp : parent.getDetailsPanel().getFields()) {
			FieldType type = fdp.getType();
			String name = fdp.getFieldName();
			String nameUpper = name.substring(0, 1).toUpperCase() + name.substring(1);
			String template = getAccessorTemplate(type);

			if (template != null) {
				template = template.replaceAll("%type%", getJavaType(type))
						.replaceAll("%varName%", name)
						.replaceAll("%varNameUpper%", nameUpper);
				if (type == FieldType.REF) {
					// TODO: Replace all occurrences of %refType% with the name of the referenced type.
				}
				rtn.append(template); //.append(CRLF);
			}
			else {
				// TODO: Throw error?
			}
		}

		return rtn.toString();
	}

}
